﻿using Nemerle.Collections;
using Nemerle.Imperative;
using Nemerle.Peg;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;

namespace Nemerle2.Compiler
{
  /// <summary>
  /// Description of LocatedList.
  /// </summary>
  [Record]
  public class LocatedList[T] : Located, IList[T]
    where T: Located
  {
    _content : array[T];

    #region System.Collections.Generic.IList[T]  Members

    public Item[index : int] : T
    {
  		[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
      get { _content[index] }
    }

  	[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    public IndexOf(item : T) : int
    {
    	Array.IndexOf(_content, item);
    }

    public Insert(index : int, item : T) : void
    {
    	_ = index; _ = item;
    	throw System.InvalidOperationException()
    }

    public RemoveAt(index : int) : void
    {
    	_ = index;
    	throw System.InvalidOperationException()
    }

    public set_Item(index : int, value : T) : void
    {
    	_ = index; _ = value;
    	throw System.InvalidOperationException()
    }

    #endregion System.Collections.Generic.IList[T]  Members

    #region System.Collections.Generic.ICollection[T]  Members

    public Add(item : T) : void
    {
    	_ = item;
    	throw System.InvalidOperationException()
    }

    public Clear() : void
    {
    	throw System.InvalidOperationException()
    }

    public Contains(item : T) : bool
    {
      for (mutable i = 0; i < _content.Length; i++)
        when (_content[i].Equals(item))
          return true;

      false
    }

  	[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    public CopyTo(ary : array[T], arrayIndex : int) : void
    {
      _content.CopyTo(ary, arrayIndex)
    }

    public Count : int
    {
    	[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
      get { _content.Length }
    }

    public IsReadOnly : bool
    {
    	[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
      get { true }
    }

    public Remove(item : T) : bool
    {
    	_ = item;
    	throw System.InvalidOperationException()
    }

    #endregion System.Collections.Generic.ICollection[T]  Members

    #region System.Collections.Generic.IEnumerable[T]  Members

    public GetEnumerator() : IEnumerator[T]
    {
    	foreach (elem in _content)
    	  yield elem;
    }

    #endregion System.Collections.Generic.IEnumerable[T]  Members

    public static Flatten(this source : LocatedList[LocatedList[T]]) : array[T]
    {
      mutable len;

      foreach (group in source._content)
        len += group._content.Length;

      def result = array(len);
      mutable pos;

      foreach (group in source._content)
      {
        group.CopyTo(result, pos);
        pos += group.Count;
      }

      result
    }

  	[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    public static Empty() : LocatedList[T]
    {
      LocatedList(Location(), array(0))
    }

  	[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    public static Empty(loc : Location) : LocatedList[T]
    {
      LocatedList(loc, array(0))
    }
  }
}
